package com.project.config;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.project.service.*;
import dev.langchain4j.agent.tool.ToolSpecification;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.chat.request.json.JsonObjectSchema;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.tool.ToolExecutor;
import dev.langchain4j.service.tool.ToolProvider;
import dev.langchain4j.service.tool.ToolProviderRequest;
import dev.langchain4j.service.tool.ToolProviderResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;
import java.util.Date;
import java.util.List;


/**
 * @Author: zhoujinchuan
 * @Description: （大语言模型配置）
 * @Date: 2025/2/21 11:03
 */
@Configuration
public class LLMConfig {

    @Bean
    public ChatLanguageModel chatLanguageModel() {
        return OpenAiChatModel.builder()
                .apiKey("sk-6592514f30eb46279298ba765edee4ab")
                .modelName("qwen-turbo")
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                // 启用请求日志
                .logRequests(true)
                // 启用响应日志
                .logResponses(true)
                // 添加监听器
                .listeners(List.of(new MyChatModelListener()))
                // 配置重试逻辑，指定重试次数和延迟等参数
                .maxRetries(5)
                // 设置10秒超时
                .timeout(Duration.ofSeconds(10))
                .build();
    }

    @Bean
    public StreamingChatLanguageModel streamingChatLanguageModel() {
        return OpenAiStreamingChatModel.builder()
                .apiKey("sk-6592514f30eb46279298ba765edee4ab")
                .modelName("qwen-turbo")
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .build();
    }

    @Bean
    public ChatAssistant chatAssistant(ChatLanguageModel chatLanguageModel) {
        return AiServices.builder(ChatAssistant.class)
                .chatLanguageModel(chatLanguageModel)
                .build();
    }

    @Bean
    public TokenSteamAssistant tokenSteamAssistant(StreamingChatLanguageModel streamingChatLanguageModel) {
        return AiServices.builder(TokenSteamAssistant.class)
                .streamingChatLanguageModel(streamingChatLanguageModel)
                .build();
    }

    @Bean
    public FluxSteamAssistant fluxSteamAssistant(StreamingChatLanguageModel streamingChatLanguageModel) {
        return AiServices.builder(FluxSteamAssistant.class)
                .streamingChatLanguageModel(streamingChatLanguageModel)
                .build();
    }

    @Bean
    public ChatMemoryAssistant  chatMemoryAssistant(StreamingChatLanguageModel chatLanguageModel) {
        return AiServices.builder(ChatMemoryAssistant.class)
                .streamingChatLanguageModel(chatLanguageModel)
                // 注意每个memoryId对应创建一个ChatMemory
                .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10))
                .build();
    }

    @Bean
    public LegalAssistant legalAssistant(ChatLanguageModel chatLanguageModel) {
        return AiServices.builder(LegalAssistant.class)
                .chatLanguageModel(chatLanguageModel)
                .build();
    }

    @Bean
    public SentimentAnalyzer sentimentAnalyzer(ChatLanguageModel chatLanguageModel) {
        return AiServices.builder(SentimentAnalyzer.class)
                .chatLanguageModel(chatLanguageModel)
                .build();
    }

    @Bean
    public PersonExtractor personExtractor(ChatLanguageModel chatLanguageModel) {
        return AiServices.builder(PersonExtractor.class)
                .chatLanguageModel(chatLanguageModel)
                .build();
    }

    @Bean
    public MyAnalyzer myAnalyzer(ChatLanguageModel chatLanguageModel) {
        return AiServices.builder(MyAnalyzer.class)
                .chatLanguageModel(chatLanguageModel)
                .build();
    }

    @Autowired
    private DemoService demoService;

    @Bean
    public FunctionAssistant functionAssistant(ChatLanguageModel chatLanguageModel) {
        return AiServices.builder(FunctionAssistant.class)
                .chatLanguageModel(chatLanguageModel)
                .toolProvider(new ToolProvider() {
                    @Override
                    public ToolProviderResult provideTools(ToolProviderRequest toolProviderRequest) {
                        String singleText = toolProviderRequest.userMessage().singleText();
                        if (singleText.contains("发票")) {
                            ToolSpecification toolSpecification = ToolSpecification.builder()
                                    .name("invoice_assistant")
                                    .description("根据用户提交的开票信息，开具发票")
                                    .parameters(JsonObjectSchema.builder()
                                            .addStringProperty("companyName","公司名称")
                                            .addStringProperty("dutyNumber","税号")
                                            .addStringProperty("amount","金额保留两位小数")
                                            .build())
                                    .build();
                            // 业务逻辑 ToolExecutor
                            ToolExecutor toolExecutor = (toolExecutionRequest, memoryId) -> {
                                String arguments1 = toolExecutionRequest.arguments();
                                System.out.println("arguments1 =>>>> " + arguments1);
                                return "开具成功";
                            };
                            return ToolProviderResult.builder()
                                    .add(toolSpecification, toolExecutor)
                                    .build();
                        }else if (singleText.contains("菜谱")){
                            ToolSpecification toolSpecification = ToolSpecification.builder()
                                    .name("菜谱")
                                    .description("根据用户日期来返回菜谱信息,今天的日期是"+ DateUtil.formatDate(new Date()))
                                    .parameters(JsonObjectSchema.builder()
                                            .addStringProperty("dateStr","日期（yyyy-MM-dd格式）")
                                            .build())
                                    .build();
                            // 业务逻辑 ToolExecutor
                            ToolExecutor toolExecutor = (toolExecutionRequest, memoryId) -> {
                                String arguments1 = toolExecutionRequest.arguments();
                                String date = (String) JSONUtil.parseObj(arguments1).get("dateStr");
                                return demoService.dd(date);
                            };
                            return ToolProviderResult.builder()
                                    .add(toolSpecification, toolExecutor)
                                    .build();
                        }
                        return null;
                    }
                })
                .build();
    }

}
